﻿using System;
using ARD.Common;
using ARD.EventRouting;

namespace SharpObjects.SearchEngine.Common.ApplicationEvents
{
    [Serializable]
    public class LogCategory
    {
        public static readonly LogCategory Debug = new LogCategory("Debug");
        public static readonly LogCategory Info = new LogCategory("Info");
        public static readonly LogCategory Warning = new LogCategory("Warning");
        public static readonly LogCategory Error = new LogCategory("Error");

        public static LogCategory CustomCategory(string categoryName) { return new LogCategory(categoryName); }

        public LogCategory(string name)
        {
            this.Name = name;
        }

        public string Name { get; set; }

        public override string ToString()
        {
            return this.Name;
        }

        public static implicit operator string(LogCategory logCategory)
        {
            return logCategory.ToString();
        }
    }

    [Serializable]
    public class LoggingApplicationEvent : IApplicationEvent
    {
        [Serializable]
        public class LogMessage
        {
            public LogMessage(string origin)
            {
                this.LogMessageOrigin = origin;
            }

            public LogMessage(Location origin)
            {
                this.LogMessageOrigin = origin;
            }

            public string LogMessageOrigin { get; set; }
            public string Message { get; set; }
            public LogCategory LogCategory { get; set; }
        }

        [Serializable]
        public class DebugMessage : LogMessage
        {
            public DebugMessage(Location origin)
                : base(origin)
            {
                this.LogCategory = LogCategory.Debug;
            }

            public DebugMessage(string origin)
                : base(origin)
            {
                this.LogCategory = LogCategory.Debug;
            }
        }

        [Serializable]
        public class InfoMessage : LogMessage
        {
            public InfoMessage(string origin)
                : base(origin)
            {
                this.LogCategory = LogCategory.Info;
            }

            public InfoMessage(Location origin)
                : base(origin)
            {
                this.LogCategory = LogCategory.Info;
            }
        }

        [Serializable]
        public class WarningMessage : LogMessage
        {
            public WarningMessage(string origin)
                : base(origin)
            {
                this.LogCategory = LogCategory.Warning;
            }

            public WarningMessage(Location origin)
                : base(origin)
            {
                this.LogCategory = LogCategory.Warning;
            }
        }

        [Serializable]
        public class ErrorMessage : LogMessage
        {
            public ErrorMessage(string origin)
                : base(origin)
            {
                this.LogCategory = LogCategory.Error;
            }

            public ErrorMessage(Location origin)
                : base(origin)
            {
                this.LogCategory = LogCategory.Error;
            }

            public ErrorMessage(string origin, Exception ex)
                : base(origin)
            {
                this.LogCategory = LogCategory.Error;
                this.Message = string.Format("EXCEPTION: {0}\nSTACK TRACE: {1}", ex.Message, ex.StackTrace);
            }

            public ErrorMessage(Location origin, Exception ex)
                : base(origin)
            {
                this.LogCategory = LogCategory.Error;
                this.Message = string.Format("EXCEPTION: {0}\nSTACK TRACE: {1}", ex.Message, ex.StackTrace);
            }
        }

        public LogMessage Message { get; set; }

        public LoggingApplicationEvent()
        {
            this.Message = null;
        }

        public LoggingApplicationEvent(LogMessage msg)
        {
            this.Message = msg;
        }
    }
}
